package com.attunlcok.unlock.task;

import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.Random;
import java.util.Arrays;

import com.attunlcok.system.service.ISysConfigService;
import com.attunlcok.unlock.constant.UnlockStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.attunlcok.common.utils.DateUtils;
import com.attunlcok.unlock.domain.AttUnlockRecord;
import com.attunlcok.unlock.domain.AttUserInfo;
import com.attunlcok.unlock.domain.AttEmailInfo;
import com.attunlcok.unlock.service.IAttUnlockRecordService;
import com.attunlcok.unlock.service.IAttUserInfoService;
import com.attunlcok.unlock.service.IAttEmailInfoService;
import com.attunlcok.unlock.service.IAttUnlockOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.File;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PreDestroy;

/**
 * IMEI解锁任务处理
 * 
 * @author ruoyi
 */
@Component("unlockTask")
public class UnlockTask {
    private static final Logger log = LoggerFactory.getLogger(UnlockTask.class);

    @Autowired
    private IAttUnlockRecordService unlockRecordService;

    @Autowired
    private IAttUserInfoService userInfoService;

    @Autowired
    private IAttEmailInfoService emailInfoService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IAttUnlockOrderService attUnlockOrderService;

    private String scriptPath;

    private String scriptEntry;

    // 最大并发任务数
    private int maxTaskCount = 2;

    // 存储正在运行的进程
    private final Map<String, Process> runningProcesses = new ConcurrentHashMap<>();

    // 任务执行的唯一标识
    private String currentTaskId;
    
    // 任务开始时间
    private long taskStartTime;

    // 美国常见名字列表
    private static final String[] FIRST_NAMES = {
        "James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Charles",
        "Mary", "Patricia", "Jennifer", "Linda", "Elizabeth", "Barbara", "Susan", "Jessica", "Sarah", "Karen"
    };

    private static final String[] LAST_NAMES = {
        "Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez",
        "Hernandez", "Lopez", "Gonzalez", "Wilson", "Anderson", "Thomas", "Taylor", "Moore", "Jackson", "Martin"
    };

    // 美国主要区号列表
    private static final String[] AREA_CODES = {
        "201", "202", "203", "205", "206", "207", "208", "209", "210", "212", "213", "214", "215", "216", "217",
        "218", "219", "224", "225", "228", "229", "231", "234", "239", "240", "248", "251", "252", "253", "254",
        "256", "260", "262", "267", "269", "270", "272", "276", "281", "301", "302", "303", "304", "305", "307",
        "308", "309", "310", "312", "313", "314", "315", "316", "317", "318", "319", "320", "321", "323", "325",
        "330", "331", "334", "336", "337", "339", "347", "351", "352", "360", "361", "386", "401", "402", "404",
        "405", "406", "407", "408", "409", "410", "412", "413", "414", "415", "417", "419", "423", "424", "425",
        "430", "432", "434", "435", "440", "442", "443", "458", "469", "470", "475", "478", "479", "480", "484",
        "501", "502", "503", "504", "505", "507", "508", "509", "510", "512", "513", "515", "516", "517", "518",
        "520", "530", "531", "534", "539", "540", "541", "551", "559", "561", "562", "563", "567", "570", "571",
        "573", "574", "575", "580", "585", "586", "601", "602", "603", "605", "606", "607", "608", "609", "610",
        "612", "614", "615", "616", "617", "618", "619", "620", "623", "626", "628", "629", "630", "631", "636",
        "641", "646", "650", "651", "657", "660", "661", "662", "667", "669", "678", "681", "682", "701", "702",
        "703", "704", "706", "707", "708", "712", "713", "714", "715", "716", "717", "718", "719", "720", "724",
        "725", "727", "731", "732", "734", "737", "740", "743", "747", "754", "757", "760", "762", "763", "765",
        "769", "770", "772", "773", "774", "775", "779", "781", "785", "786", "801", "802", "803", "804", "805",
        "806", "808", "810", "812", "813", "814", "815", "816", "817", "818", "828", "830", "831", "832", "843",
        "845", "847", "848", "850", "854", "856", "857", "858", "859", "860", "862", "863", "864", "865", "870",
        "872", "878", "901", "903", "904", "906", "907", "908", "909", "910", "912", "913", "914", "915", "916",
        "917", "918", "919", "920", "925", "928", "929", "930", "931", "934", "936", "937", "938", "940", "941",
        "947", "949", "951", "952", "954", "956", "959", "970", "971", "972", "973", "975", "978", "979", "980",
        "984", "985", "989"
    };

    private final Random random = new Random();

    @PreDestroy
    public void cleanup() {
        // 终止所有运行中的进程
        for (Map.Entry<String, Process> entry : runningProcesses.entrySet()) {
            try {
                Process process = entry.getValue();
                if (process.isAlive()) {
                    process.destroy();
                    if (process.isAlive()) {
                        process.destroyForcibly();
                    }
                }
            } catch (Exception e) {
                log.error("终止进程时发生错误: " + entry.getKey(), e);
            }
        }
        runningProcesses.clear();
    }

    /**
     * 执行IMEI解锁任务
     */
    public void executeUnlockTask() {
        // 生成任务唯一标识
        currentTaskId = "task-" + System.currentTimeMillis();
        taskStartTime = System.currentTimeMillis();
        
        try {
            log.info("开始执行IMEI解锁任务，任务ID: {}", currentTaskId);

            // 1. 首先查询状态为待处理的记录
            AttUnlockRecord queryRecord = new AttUnlockRecord();
            queryRecord.setUnlockStatus(UnlockStatus.PENDING);
            List<AttUnlockRecord> records = unlockRecordService.selectAttUnlockRecordList(queryRecord);
            
            // 如果没有待处理的记录，则查询技术失败的记录
            if (records == null || records.isEmpty()) {
                queryRecord.setUnlockStatus(UnlockStatus.TECH_FAILED);
                records = unlockRecordService.selectAttUnlockRecordList(queryRecord);
            }

            if (records.isEmpty()) {
                log.info("没有需要处理的解锁记录");
                return;
            }

            // 获取配置
            scriptPath = configService.selectConfigByKey("scriptPath");
            scriptEntry = configService.selectConfigByKey("scriptEntry");
            
            // 从配置中获取最大并发任务数
            String maxTaskCountStr = configService.selectConfigByKey("maxTaskCount");
            maxTaskCount = maxTaskCountStr != null ? Integer.parseInt(maxTaskCountStr) : 2;
            
            log.info("当前配置 - 最大并发任务数: {}", maxTaskCount);
            
            // 只取maxTaskCount数量的任务
            List<AttUnlockRecord> batchRecords = records.size() > maxTaskCount ? 
                records.subList(0, maxTaskCount) : records;
            
            log.info("本次将处理 {} 条记录", batchRecords.size());

            // 为所有记录分配用户和邮箱信息
            for (AttUnlockRecord record : batchRecords) {
                assignUserAndEmail(record);
            }

            // 更新记录状态为处理中
            for (AttUnlockRecord record : batchRecords) {
                record.setUnlockStatus(UnlockStatus.PROCESSING);
                unlockRecordService.updateAttUnlockRecord(record);
            }

            // 一次性处理所有记录
            processBatchRecords(batchRecords, 0);

            log.info("所有解锁任务处理完成，任务ID: {}", currentTaskId);

        } catch (Exception e) {
            log.error("执行IMEI解锁任务时发生错误: {}", e.getMessage());
        } finally {
            cleanup();
            currentTaskId = null;
            taskStartTime = 0;
        }
    }

    /**
     * 处理批量记录
     */
    private void processBatchRecords(List<AttUnlockRecord> records, int taskIndex) {
        // 为每个批次生成唯一的任务ID
        String taskId = currentTaskId + "-batch-" + taskIndex;
        
        try {
            // 构建所有任务的参数
            StringBuilder tasksParam = new StringBuilder();
            for (int i = 0; i < records.size(); i++) {
                AttUnlockRecord record = records.get(i);
                tasksParam.append(String.format("%d,%s,%s,%s,%s,%s",
                    record.getId(),
                    record.getImei(),
                    record.getEmail(),
                    record.getFirstName() != null ? record.getFirstName() : "",
                    record.getLastName() != null ? record.getLastName() : "",
                    record.getPhone() != null ? record.getPhone() : ""
                ));
                
                if (i < records.size() - 1) {
                    tasksParam.append(";");
                }
            }

            // 执行任务
            executeTask(tasksParam.toString(), taskId);

        } catch (Exception e) {
            log.error("处理任务 " + taskId + " 时发生错误", e);
        }
    }

    /**
     * 生成随机美国手机号
     */
    private String generateUSPhoneNumber() {
        String areaCode = AREA_CODES[random.nextInt(AREA_CODES.length)];
        // 生成后7位随机数
        String firstPart = String.format("%03d", random.nextInt(900) + 100);
        String secondPart = String.format("%04d", random.nextInt(10000));
        // 直接拼接10位数字
        return areaCode + firstPart + secondPart;
    }

    /**
     * 生成随机用户名
     */
    private String[] generateRandomName() {
        String firstName = FIRST_NAMES[random.nextInt(FIRST_NAMES.length)];
        String lastName = LAST_NAMES[random.nextInt(LAST_NAMES.length)];
        return new String[]{firstName, lastName};
    }

    /**
     * 为记录分配用户和邮箱信息
     */
    private void assignUserAndEmail(AttUnlockRecord record) {
        try {
            if (record.getEmailInfoId() == null) {
                // 获取未使用的邮箱信息
                AttEmailInfo emailQuery = new AttEmailInfo();
                emailQuery.setIsUsed("0");
                emailQuery.setStatus("0");
                List<AttEmailInfo> availableEmails = emailInfoService.selectAttEmailInfoList(emailQuery);

                if (availableEmails.isEmpty()) {
                    log.error("没有可用的邮箱信息，IMEI: {}", record.getImei());
                    return;
                }

                // 选择第一个可用的邮箱
                AttEmailInfo selectedEmail = availableEmails.get(0);

                // 生成随机用户信息
                String[] randomName = generateRandomName();
                String phoneNumber = generateUSPhoneNumber();

                // 更新解锁记录
                record.setEmailInfoId(selectedEmail.getId());
                record.setFirstName(randomName[0]);
                record.setLastName(randomName[1]);
                record.setPhone(phoneNumber);
                record.setEmail(selectedEmail.getEmail());
                record.setPassword(selectedEmail.getPassword());
                record.setUpdateTime(DateUtils.getNowDate());

                // 更新邮箱状态
                selectedEmail.setIsUsed("1");
                selectedEmail.setLastUsedTime(DateUtils.getNowDate());
                selectedEmail.setUsedCount(selectedEmail.getUsedCount() + 1);
                selectedEmail.setUpdateTime(DateUtils.getNowDate());

                // 保存更改
                unlockRecordService.updateAttUnlockRecord(record);
                emailInfoService.updateAttEmailInfo(selectedEmail);
                
                log.info("为IMEI: {} 生成随机用户信息 - 姓名: {} {}, 电话: {}", 
                    record.getImei(), record.getFirstName(), record.getLastName(), record.getPhone());
            }
        } catch (Exception e) {
            log.error("分配用户和邮箱信息时发生错误，IMEI: " + record.getImei(), e);
        }
    }

    /**
     * 执行任务脚本
     */
    private void executeTask(String tasksParam, String taskId) {
        try {
            // 构建Python脚本路径
            String scriptFullPath = scriptPath + File.separator + scriptEntry;
            
            // 构建命令
            List<String> command = Arrays.asList(
                "python",
                "-m",
                "att_unlock",  // 使用模块方式执行
                "batch",      // 使用batch子命令
                "--workers", String.valueOf(maxTaskCount),  // 使用配置的maxTaskCount
                "--tasks", tasksParam
            );
            
            // 打印完整命令
            log.info("执行命令: {}", String.join(" ", command));
            
            ProcessBuilder processBuilder = new ProcessBuilder(command);
            
            // 设置工作目录为Python项目的父目录
            processBuilder.directory(new File(scriptPath).getParentFile());
            
            // 设置环境变量以确保正确的编码
            Map<String, String> env = processBuilder.environment();
            env.put("PYTHONIOENCODING", "gb2312");
            
            // 合并错误流到标准输出流
            processBuilder.redirectErrorStream(true);

            // 启动进程
            Process process = processBuilder.start();
            
            // 将进程添加到管理Map中
            runningProcesses.put(taskId, process);

            // 同步读取输出
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "gb2312"))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    log.info("任务 {} 输出: {}", taskId, line);
                }
            }

            // 等待进程完成
            int exitCode = process.waitFor();
            log.info("任务 {} 执行完成，退出码: {}", taskId, exitCode);

        } catch (Exception e) {
            log.error("执行任务 " + taskId + " 时发生错误", e);
        } finally {
            // 从管理Map中移除进程
            runningProcesses.remove(taskId);
        }
    }
} 